Verwendete Packages und
Vorgehen
Für die verwendung dieses Notebooks benötigen Sie die folgenden
installatierten Packages:
- tidyverse
- plotly
- RColorBrewer
- ggplot2
- dplyr
- plotrix
Als Datensatz wird 2021-2022 Football Team Stats verwendet,
den bei Kaggle https://www.kaggle.com/datasets/vivovinco/20212022-football-team-stats
gefunden wurde. Es geht dabei um eine Statistik von Fußball
Meisterschaften aus den 5 Besten Europa Ligas(Frankreich,
Deutschland,Spanien,Italien und England).Darin gibt es insgesamt 20
Merkmale bzw Atribute wie(Attendance, Goalscored, Bestscorer, Pts, GD,
usw.), die im folgenden erläutert werden. Rk: vom Datentyp
Numeric entspricht die Platzierung der Mannschaft im Datensatz.Sie
werden in der absteigenden Reihenfolge sortiert. D.h die Mannschaft mit
der höchsten erreichten Punkte zu den niedrigsten. Squad: vom
Datentyp Character ist der Name der Mannschaft,Country:vom
Datentyp Character ist Name des Landes, LgRk: vom Datentyp
Numeric ist die Position der Mannschaft in seiner Meisterschaft,
MP: vom Datentyp Numeric ist die Anzahl von gespielten Spiele,
W: vom Datentyp Numeric ist die Anzahl der gewonnenen Spiele,
D: vom Datentyp Numeric ist die Anzahl Unentschiedene Spiele,
L:vom Datentyp Numeric ist die Anzahl der verlorenen Spiele,
GF:vom Datentyp Numeric ist die Anzahl der erzielten Tore,
GA: vom Datentyp Numeric ist die Anzah der kassierten Tore,
GD: vom Datentyp Numeric entspricht die Tordifferenz,
Pts: Punktstand, Pts/G: Punkte pro Spiel,
xG:erwartete Tore, xGA:erwartete kassierte Tore,
xGD:erwartete Tordifferenz, xGD/90:erwartete
Tordifferenz nach 90 Minuten, Last 5: letzte funf Ergebnisse,
Attendance:Durchschnitt der Besucherzahl im Stadion,
BestScorer GoalScored:vom Datentyp Character entspricht den
Name des Bestschiessers und Anzahl der erzielten Tore,
Goalkeeper: Torwart
Diese Merkmale sind aber nicht vollständig bzw illustrieren nicht
ganz genau die Mannschaften. Es gibt andere Merkmale wie die Anzahl der
Roten und Gelben Karten, die Anzahl von Fehlern, erfolgreiche Pässe,
Zweikämpfe usw., die die Meisterschaften besser illustrieren können. Die
verfügbare Merkmale sind nur ein Teil einer größeren Obermenge.
Der Datensatz wird ganz einfach mithilfe von read_delim eingelesen,
da die Merkmale durch ein Semikolon getrennt werden. Danach werden sie
in einem Data frame ausgelagert. Der Grund dafür ist einfach. Mit einem
Data frame und mithilfe von dem Pipeline, Filter, select, mutate,usw.
ist es möglich nur auf bestimmte Merkmale zuzugreifen und das
vereinfacht die Visualisierung.
Untersuchung
Bei der Betrachtung eines Datensatzes bzw eines Fußball Datensatzes
kann man sich unterschiedlichen Fragen stellen und zwar: 1) Was sind die
Absoluten Häufigkeiten der verfügbaren Länder(Wieviel mal kommen die
Länder vor)? 2) Wie sieht die Besucherzahl im Stadien aus? D.h in
welcher Liga werden die Spiele mehr oder weniger besucht? 3)Was ist Das
Punktverhältnis zwischen die Länder? D.h wieviele Punkte wurden in Jedem
Land durch die Mannschaften erreicht? 4) Welche Mannschaften verlieren
bzw gewinnen weniger oder mehr als den Schnitt? 5)Welche Mannschaften
Scoren viel oder weniger als den Schnitt und in welchen Länder gibt es
die besten Scorer. usw.. ==> und Vieles mehr.. Diese Fragen werden
wir einfach mitfhilfe von ggplot und ggplotly visualisieren und danach
interpretieren, was wir erfunden haben.
Häufigkeiten der
Länder
In unserem Datensatz gibt es insgesamt 98 Mannschaften. Wir wollen
erstmal sehen, wie sich die Mannschaften in den Länder verteilen. D.h
wie viel Mannschaften jedes Land beinhaltet. Dafür benutzen wir einen
Barplot und wir greifen auf die Spalte Country, die die Namen der Länder
enthält, zu. Am Ende wird nun einen Barplot mit unterschiedlichen Farben
und eine Legende hinzugefügt.
count<-table(X2021_2022_Football_Team_Stats$Country)
p2<-barplot(count,main="5 Besten Europa Meisterschaften und Ihre Häufigkeiten",xlab="Name der Länder",ylab="Absolute Häufigkeiten",legend=rownames(count),col=c("green","red","blue","orange","yellow"))

Aus der Visualisierung ist es zu bemerken, dass die Häufigkeiten der
Länder pro Mannschaft fast gleich aussieht. Jedes Land enthält in
unserem Datensatz 20 Mannschaften, nur die Deutsche Liga besteht aus 18
Mannschaften.
Menschenmassen in
Stadien
Hierbei wollen wir herausfinden, wie viele Mannschaften pro Land
wenig besucht werden. Dafür nehmen wir die Spalte Attendance.
Diese Spalte enthält die durchschnittliche Besucherzahl der Mannschaften
nach 37 SpielTage. Dann machen wir eine mutate mit der Spalte
average. Dies entspricht den Durschnitt von den 98
Mannschaften. Zum schluss machen wir eine Filterung von Ländern, die
unterhalb der Spalte average liegen und wir machen eine
Selektion von den Name des Landes(Country),Name der Mannschaft(Squad)
und Attendance. Dieser Histogramm wird Rot gefarbt,um
anzudeuten, dass die Mannschaften etwas schlechtes (kleine Besucherzahl)
aufweisen
hallo2<- Erg %>%
mutate(
average=sum(Attendance)/98,
) %>%
filter(Attendance<average) %>%
select(Squad, Country,Attendance)
p<-ggplot(hallo2 , mapping=aes(x=Country)) +
geom_histogram(fill="red", color="red",stat="count" , breaks=seq(0, 20,4)) +
labs(
title="5 Besten Meisterschaften",
subtitle="Anzahl von Mannschaften pro Land mit wenigen Attendance",
x="Name von Länder",
y="Absolute Häufigkeiten"
) +
coord_flip()
Warning: Ignoring unknown parameters: binwidth, bins, pad, breaks
Aus dieser Visualisierung folgt, dass alle Länder auherhalb
Großbritanien eine Schlechte Besucherzahl bei den Spielen aufweisen. Die
schechteste Davon ist Italien Mit 80% der Mannschaften mit einer
Besucherzahl unter dem Schnitt. Nur die Englische Liga wird über 85 %
der Spiele über den Schnitt besucht.
Punktverhältnis der
Länder und Pie Chart Verteilung
Hier wollen wir sehen wieviele Punkte wurden in jeder
Ligameisterschaft nach 37 Spieltage gesammelt. Dafür machen wir eine
Gruppierung nach der Spalte Country. Dann die Summe von
Pts(Pts ist dabei die erreichendete Punkte Pro Mannschaft nach
37 Spieltage). Diese Summe wird dann Pro Land jeweils in einer neuen
Mutate Spalte(summe) hinzugefügt. Zum Schluss machen wir eine
Selektion der Spalten Country(Name der Länder), Squad(Mannschaft
Name),summe(die neue Spalte).
hallo3 <- Erg %>%
group_by(Country) %>%
mutate(
summe=sum(Pts),
) %>%
select(Squad, Country,summe)
p2<-ggplot(hallo3,aes(Country, summe)) +
geom_point(size = 3) +
geom_line()+
labs(
title="5 Besten Länder und die Summe ihrer gesamten Punkten",
x="Name von Länder",
y="Gesamte Summe der Punkten"
)
ggplotly(p2)
Im zweiten Pie Chart Verteilung nehmen wir einfach die vorherigen
berechneten Summe Pro Länder und Wir repräsentieren jedes Land mit
seiner Prozentualen Leistung nach der Saison. Als Farbe benutzen wir die
unterschiedlichen Farben des Regenbogens, um die Länder miteinander zu
unterscheiden.
slices<- c(1009,1009,1001,845,1010)
lbls<-c("England","Italien","Spanien","Deutschland","Frankreich")
pct<-round(slices/sum(slices)*100)
lbls<-paste(lbls, " ",pct, "%", seq="" )
pie(slices ,labels=lbls, main="Pie Chart Verteilung der Länder nach der Saison", col=rainbow(5))

Bemerkenswert ist das 4 Länder(Frankreich, Großbritannien,Spanien und
Italien) nach 37 Spieltage die gleiche aufgerundete Leistung erbracht
haben nämlich 21%. Nur Deutschland hat nur 17% erbracht. Ein möglicher
Grund dafür besteht darin, dass es in der Deutschen Liga nur 18
Mannschaften gibt, wenn die anderen über 20 Mannschaften verfügen. D.h
es wird kaum vorkommen, dass die erreichte Punkte in Deutschland am Ende
der Saison gleich wie in anderen Länder aussieht, da die
Mannschaftenanzahl kleiner ist.
Mannschaften mit gutem
Tordifferenz
In dieser Visualisierung wollen wir bestimmen, welche Mannschaften
eine gute Tordifferenz besitzt. Dafür benötigen wir die Spalte
GD(Goal Difference =Tore erzielt minus Tore Kassiert). Diese
Spalte enthält dann die Tordifferenz von jeder Mannschaft nach 37
Spieltage. Wir machen dann eine Mutate mit der Spalte average.
Dies entspricht den Schnitt der Tordifferenzen aller Mannschaten. Danach
machen wir eine Filterung der Mannschaften die oberhalb der Average
liegen und zum Schluss eine Selektion der Spalten(Squad, GD und
average)
hallo7<-Erg %>%
mutate(
average=sum(GD)/98
) %>%
filter(GD> average) %>%
select(Squad,GD,average)
p6<-ggplot(hallo7) +
geom_point(mapping=aes(x=GD, y=Squad),
color="brown",fill="brown") +
labs(
title=" gute Mannschaften mit Tordifferenz ober den Schnitt ",
y="Name von Mannschaften",
x="Tordifferenz der Mannschaften"
)
ggplotly(p6)
Aus dieser Visualisierung lässt sich herausfinden,dass ungefähr 46%
der verfügbaren Mannschaften eine Tordifferenz über den Durchschnitt
besitzen. Dabei ist immer die englische Meisterschaft an der Spitze mit
mehr als ein drittel der Mannschaften und an letzten Stelle steht die
Italienische Meisterschaft mit nur 7 Mannschaften.
Mannschaften die mehr
als den Schnitt gewonnen haben
Hierbei wollen wir die Mannschaften, die über den Schnitt
gewinnen.Dabei greifen wir auf die Spalte W zu. Diese Spalte
enthält alle gewonnenen Spiele der Mannschaften nach 37 Spiele. Wir
machen wie üblich eine neue Spalte, die die Average der gewonnenen
Spiele berechnet und am Ende eine Filter der Merkmale die oberhalb
liegen und eine Selektion der Spalten(Squad, W und die neue Spalte
Average).
hallo5<-Erg %>%
mutate(
average=sum(W)/98
) %>%
filter(W> average) %>%
select(Squad,W,average)
p3<-ggplot(hallo5) +
geom_point(mapping=aes(x=W, y=Squad),
color="blue",fill="blue") +
labs(
title=" Beste Mannschaften die ueber der Average gewinnen",
y="Name von Mannschaften",
x="Anzahl von gewonnenen Spielen"
)
ggplotly(p3)
Bei der Gewinnquote zeigt immer noch die Englische Meisterschaft,
warum sie als beste Fussball Liga gilt. Manchester city aus
England steht immer noch an der Spitze mit mehr als den Doppel des
Durchschnitts. Hierbei ist die französische Liga an der letzten Stelle
mit wenigen Mannschaften Dabei.
Spieler mit der Besten
GPMA(Tor pro Spiel Durchschnitt)
GPMA=Anzahl von erzielten Toren/ Anzahl von Spielen . Zum ersten wird
einen neuen Datensatz hallogt erstellt, wobei die Spalte
Top Team Scorer in Zwei Spalten(BestScorer und
GoalScored) geteilt wird. Eine Spalte mit dem Name des
Schießers und eine andere Mit seinen erzielten Toren. Danach erzeugen
wir die Spalte GPMA und die Spalte Average . GPMA
entspricht den Torschnitt von jedem Spieler nach der Anzahl der
gespielten Spiele. Average ist einfach der Schnit der GPMA
aller Mannschaften.
hallogt<-Erg %>% separate(col = "Top Team Scorer", into = c("BestScorer","GoalScored"), sep=" - ")
hallo11<- hallogt %>%
mutate(
GPMA=as.numeric(GoalScored)/MP,
Average=sum(GPMA)/98
) %>%
filter(GPMA> Average) %>%
select(BestScorer, GoalScored ,GPMA,Country)
p9<-ggplot(hallo11) +
geom_point(mapping=aes(x=GPMA , y=BestScorer ),
color="maroon",fill="maroon") +
labs(
title=" Schiesser die über den GPMA scoren",
y="Name der Spieler",
x="Tor pro Spiel Durchschnitt der Spieler"
)
ggplotly(p9)
Schiessverhältnis
zwischen die Ligas mit BestSchießer über den Schnitt
Zum ersten wird einen neuen Dataframe hallogt erstellt,
wobei die Spalte Top Team Scorer in Zwei
Spalten(BestScorer und GoalScored) geteilt wird. Eine
Spalte mit dem Name des Schießers und eine andere Mit seinen erzielten
Toren. Danach machen wir eine Gruppierung über die Spalte
Country und eine neue Spalte Average wird hinzugefügt.
Dies enthält den Schnitt der erzielten Toren und am Ende machen wir eine
Selektion der erzielten Tore oberhalb der Average
hallogt<-Erg %>% separate(col = "Top Team Scorer", into = c("BestScorer","GoalScored"), sep=" - ")
hallo10<-hallogt %>%
group_by(Country)%>%
mutate(
Average=sum(as.numeric(GoalScored))/98
) %>%
filter(GoalScored > Average) %>%
select(BestScorer, GoalScored ,Average,Country)
p8<-ggplot(hallo10 , mapping=aes(x=Country)) +
geom_bar(fill="orange", color="black") +
labs(
title=" Ligas Goalausgleich",
subtitle=" Ligas mit mehr und Weniger BestSchießer",
x="Name von Länder",
y="Anzahl der BestSchießer pro Land"
)
ggplotly(p8)
Die Deutsche Liga hat wenige Mannschaften als die andere Länder aber
besitzt ein Drittel der besseren ToreSchießer der lertzten Saison. Zu
beachten ist, dass Italien mit nur 6 Beteiligten steht immer an der
letzten Stelle. Die Italienische Liga wird nicht nur unter den Schnitt
besichtigt, sondern die Mannschaften und Spieler schießen nicht so
viele. Diese Gründe weisen einfach nach, warum die Italienische Liga als
schwere Liga gekennzeichnet wird.
überraschende
Ergebnisse
ein größes überraschendes Ergebnis besteht darin, dass insgesamt 4
Meisterschaften(Großbritannien, Frankreich, Italien und Spanien) die
gleiche aufgerundete Leistung(jeweils 21% der punkten) am Ende der
Saison gesammelt haben. Sie verfügen über unterschiedliche Tordiffernz,
Erwartete Toren , Bestschießer und bei manchen Meisterschaften gibt es
sogar mehr als 50 % der Meisterschaften, die wenig Tore erzielen. Wir
können darunter verstehen, dass die Torquote einer Mannschaft keinen
Stärkeren Einfluss auf den Gewinn oder Verlust eines Spiels hat.
Eine weitere Überraschung liegt daran, dass die Deutsche
Meisterschaft wenige Spieler bzw Stürmer hat, weil sie nur 18
Mannschaften hat, wenn die anderen Ligas über 20 Verfügen. Sie aber die
Liga mit den besten Stürmer die mehr als den Schnitt schießen.
Kristischer
Ausblick
Es ist immer schwer seine eigene Arbeit zu beurteilen, aber nur die
eigene Beiteiligten wissen, welcher Aufwand und welche Schwierigkeiten
sie bei der Erledigung der Arbeit erlebt haben. In dieser Arbeit war die
Idee mit einem Flexdashboard(in den beiden ersten versionen) die Daten
zu visualisieren ungeeignet. Der Grund dafür ist einfach. Damit kann man
nicht gleichzeitig visualisieren und Text hinzufügen, bzw den Code
ansehen. Aber nach zwei Versionen ist ein Notebook für diese
Visualisierung zum Einsatz gekommen und hat uns die Sachen erleichtert
und die Visualisierungen ist unserer Meinung nach nachvollziehbarer
geworden. Besser hätten wir direkt mit einem Notebook angefangen und wir
wären früh fertig geworden. Aber dies hat uns ermöglicht sowohl mit
Flexdashboard als auch Notebook zu arbeiten. Das kann für uns nur ein
Vorteil sein.
Verwendete Quellen https://www.delftstack.com/de/howto/r/separate-in-r/:
Wurde benutzt, weil wir eine Spalte in zwei Spalten aufteilen
wollten.
Character Encoding in the RStudio IDE – RStudio Support: Mit UTF-8
haben wir Probleme zum Einlesen Manche Charakter gekriegt Daher haben
wir uns diese Encoding Quelle Seite angeschaut, um unsere passende
Encoding auszuwählen.
Geleisteten Arbeitszeit
Zur Erledigung dieser Arbeit haben wir ungefähr 47 Stunden.(innerhalb
4 Wochen) für die erste Version gebraucht. Für die zweite Version 10
Stunden innerhalb einer Woche.Für die dritte Version haben wir 23
Stunden gebraucht, um es fertigzustellen. Das ergibt eine gesamte
Arbeitsaufwand von 80 Stunden.
LS0tDQp0aXRsZTogIkZ1w59iYWxsIEFuYWx5c2UgZGVyIGxldHp0ZW4gU2Fpc29uIGF1cyBkZW4gNSBCZXN0ZW4gRXVyb3BhIExpZ2FtZWlzdGVyc2NoYWZ0ZW4gIg0KYXV0aG9yOiAiSGFuYW4gV2FuZGppIg0Kb3V0cHV0OiANCiAgaHRtbF9ub3RlYm9vazoNCiAgICBoaWdobGlnaHQ6IHB5Z21lbnRzDQogICAgbnVtYmVyX3NlY3Rpb25zOiB5ZXMNCiAgICB0aGVtZTogY29zbW8NCiAgICB0b2M6IHllcw0KICAgIGVuY29kaW5nOiB1dGYtOCAgIA0KICBodG1sX2RvY3VtZW50OiANCiAgICBmaWdfY2FwdGlvbjogeWVzDQogICAgdGhlbWU6IGNvc21vDQogICAgaGlnaGxpZ2h0OiBweWdtZW50cw0KICAgIG51bWJlcl9zZWN0aW9uczogeWVzDQogICAgdG9jOiB5ZXMNCiAgICB0b2NfZmxvYXQ6IHllcw0KZW5jb2Rpbmc6IHV0Zi04DQotLS0NCg0KDQpgYGB7ciBzZXR1cCwgaW5jbHVkZSA9IEZBTFNFfQ0KbGlicmFyeShkcGx5cikNCnN1cHByZXNzUGFja2FnZVN0YXJ0dXBNZXNzYWdlcyhsaWJyYXJ5KGRwbHlyKSkNCmxpYnJhcnkocGxvdHJpeCkNCmxpYnJhcnkoZ2dwbG90MikNCmxpYnJhcnkocGxvdGx5KQ0KbGlicmFyeShSQ29sb3JCcmV3ZXIpDQpzdXBwcmVzc1BhY2thZ2VTdGFydHVwTWVzc2FnZXMobGlicmFyeShSQ29sb3JCcmV3ZXIpKQ0KbGlicmFyeSh0aWR5dmVyc2UpDQpzdXBwcmVzc1BhY2thZ2VTdGFydHVwTWVzc2FnZXMobGlicmFyeSh0aWR5dmVyc2UpKQ0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGZpZy53aWR0aCA9IDUsIGZpZy5hc3AgPSAxLzMpDQpYMjAyMV8yMDIyX0Zvb3RiYWxsX1RlYW1fU3RhdHMgPC0gcmVhZF9kZWxpbSgiQzovVXNlcnMvSEFOQU4gV0FOREpJL0Rlc2t0b3AvVkRBL2RhdGEvMjAyMS0yMDIyIEZvb3RiYWxsIFRlYW0gU3RhdHMuY3N2IiwgDQogICAgZGVsaW0gPSAiOyIsIGVzY2FwZV9kb3VibGUgPSBGQUxTRSwgbG9jYWxlID0gbG9jYWxlKGVuY29kaW5nID0gIklTTy04ODU5LTIiKSwgDQogICAgdHJpbV93cyA9IFRSVUUpDQoNCiAgICANCkVyZzwtIGFzLmRhdGEuZnJhbWUoWDIwMjFfMjAyMl9Gb290YmFsbF9UZWFtX1N0YXRzKQ0KDQpgYGANCg0KDQojIFZlcndlbmRldGUgUGFja2FnZXMgdW5kIFZvcmdlaGVuDQpGw7xyIGRpZSB2ZXJ3ZW5kdW5nIGRpZXNlcyBOb3RlYm9va3MgYmVuw7Z0aWdlbiBTaWUgZGllIGZvbGdlbmRlbiBpbnN0YWxsYXRpZXJ0ZW4gUGFja2FnZXM6DQoNCi0gdGlkeXZlcnNlDQotIHBsb3RseQ0KLSBSQ29sb3JCcmV3ZXINCi0gZ2dwbG90Mg0KLSBkcGx5cg0KLSBwbG90cml4DQoNCg0KQWxzIERhdGVuc2F0eiB3aXJkICoyMDIxLTIwMjIgRm9vdGJhbGwgVGVhbSBTdGF0cyogdmVyd2VuZGV0LCBkZW4gYmVpICpLYWdnbGUqIGh0dHBzOi8vd3d3LmthZ2dsZS5jb20vZGF0YXNldHMvdml2b3ZpbmNvLzIwMjEyMDIyLWZvb3RiYWxsLXRlYW0tc3RhdHMgIGdlZnVuZGVuIHd1cmRlLiBFcyBnZWh0IGRhYmVpIHVtIGVpbmUgU3RhdGlzdGlrIHZvbiBGdcOfYmFsbCBNZWlzdGVyc2NoYWZ0ZW4gYXVzIGRlbiA1IEJlc3RlbiBFdXJvcGEgTGlnYXMoRnJhbmtyZWljaCwgRGV1dHNjaGxhbmQsU3BhbmllbixJdGFsaWVuIHVuZCBFbmdsYW5kKS5EYXJpbiBnaWJ0IGVzIGluc2dlc2FtdCAyMCBNZXJrbWFsZSBiencgQXRyaWJ1dGUgd2llKEF0dGVuZGFuY2UsIEdvYWxzY29yZWQsIEJlc3RzY29yZXIsIFB0cywgR0QsIHVzdy4pLCBkaWUgaW0gZm9sZ2VuZGVuIGVybMOkdXRlcnQgd2VyZGVuLg0KKlJrKjogdm9tIERhdGVudHlwIE51bWVyaWMgZW50c3ByaWNodCBkaWUgUGxhdHppZXJ1bmcgZGVyIE1hbm5zY2hhZnQgaW0gRGF0ZW5zYXR6LlNpZSB3ZXJkZW4gaW4gZGVyIGFic3RlaWdlbmRlbiBSZWloZW5mb2xnZSBzb3J0aWVydC4gRC5oIGRpZSBNYW5uc2NoYWZ0IG1pdCBkZXIgaMO2Y2hzdGVuIGVycmVpY2h0ZW4gUHVua3RlIHp1IGRlbiBuaWVkcmlnc3Rlbi4NCipTcXVhZCo6IHZvbSBEYXRlbnR5cCBDaGFyYWN0ZXIgaXN0IGRlciBOYW1lIGRlciBNYW5uc2NoYWZ0LCpDb3VudHJ5Kjp2b20gRGF0ZW50eXAgQ2hhcmFjdGVyIGlzdCAgTmFtZSBkZXMgTGFuZGVzLCAqTGdSayo6IHZvbSBEYXRlbnR5cCBOdW1lcmljIGlzdCBkaWUgUG9zaXRpb24gZGVyIE1hbm5zY2hhZnQgaW4gc2VpbmVyIE1laXN0ZXJzY2hhZnQsICpNUCo6IHZvbSBEYXRlbnR5cCBOdW1lcmljIGlzdCBkaWUgQW56YWhsIHZvbiBnZXNwaWVsdGVuIFNwaWVsZSwgKlcqOiB2b20gRGF0ZW50eXAgTnVtZXJpYyBpc3QgZGllIEFuemFobCBkZXIgZ2V3b25uZW5lbiBTcGllbGUsICpEKjogdm9tIERhdGVudHlwIE51bWVyaWMgaXN0IGRpZSBBbnphaGwgVW5lbnRzY2hpZWRlbmUgU3BpZWxlLCAqTCo6dm9tIERhdGVudHlwIE51bWVyaWMgaXN0IGRpZSBBbnphaGwgZGVyIHZlcmxvcmVuZW4gU3BpZWxlLCAqR0YqOnZvbSBEYXRlbnR5cCBOdW1lcmljIGlzdCBkaWUgQW56YWhsIGRlciBlcnppZWx0ZW4gVG9yZSwgKkdBKjogdm9tIERhdGVudHlwIE51bWVyaWMgaXN0IGRpZSBBbnphaCBkZXIga2Fzc2llcnRlbiBUb3JlLCAqR0QqOiB2b20gRGF0ZW50eXAgTnVtZXJpYyBlbnRzcHJpY2h0IGRpZSBUb3JkaWZmZXJlbnosICpQdHMqOiBQdW5rdHN0YW5kLCAqUHRzL0cqOiBQdW5rdGUgcHJvIFNwaWVsLCAqeEcqOmVyd2FydGV0ZSBUb3JlLCAqeEdBKjplcndhcnRldGUga2Fzc2llcnRlIFRvcmUsICp4R0QqOmVyd2FydGV0ZSBUb3JkaWZmZXJlbnosICp4R0QvOTAqOmVyd2FydGV0ZSBUb3JkaWZmZXJlbnogbmFjaCA5MCBNaW51dGVuLCAqTGFzdCA1KjogbGV0enRlIGZ1bmYgRXJnZWJuaXNzZSwgKkF0dGVuZGFuY2UqOkR1cmNoc2Nobml0dCBkZXIgQmVzdWNoZXJ6YWhsIGltIFN0YWRpb24sICpCZXN0U2NvcmVyIEdvYWxTY29yZWQqOnZvbSBEYXRlbnR5cCBDaGFyYWN0ZXIgZW50c3ByaWNodCBkZW4gTmFtZSBkZXMgQmVzdHNjaGllc3NlcnMgdW5kIEFuemFobCBkZXIgZXJ6aWVsdGVuIFRvcmUsICpHb2Fsa2VlcGVyKjogVG9yd2FydA0KDQpEaWVzZSBNZXJrbWFsZSBzaW5kIGFiZXIgbmljaHQgdm9sbHN0w6RuZGlnIGJ6dyBpbGx1c3RyaWVyZW4gbmljaHQgZ2FueiBnZW5hdSBkaWUgTWFubnNjaGFmdGVuLiBFcyBnaWJ0IGFuZGVyZSBNZXJrbWFsZSB3aWUgZGllIEFuemFobCBkZXIgUm90ZW4gdW5kIEdlbGJlbiBLYXJ0ZW4sIGRpZSBBbnphaGwgdm9uIEZlaGxlcm4sIGVyZm9sZ3JlaWNoZSBQw6Rzc2UsIFp3ZWlrw6RtcGZlIHVzdy4sIGRpZSBkaWUgTWVpc3RlcnNjaGFmdGVuIGJlc3NlciBpbGx1c3RyaWVyZW4ga8O2bm5lbi4gRGllIHZlcmbDvGdiYXJlIE1lcmttYWxlIHNpbmQgbnVyIGVpbiBUZWlsIGVpbmVyIGdyw7bDn2VyZW4gT2Jlcm1lbmdlLg0KDQpEZXIgRGF0ZW5zYXR6IHdpcmQgZ2FueiBlaW5mYWNoIG1pdGhpbGZlIHZvbiByZWFkX2RlbGltIGVpbmdlbGVzZW4sIGRhIGRpZSBNZXJrbWFsZSBkdXJjaCBlaW4gU2VtaWtvbG9uIGdldHJlbm50IHdlcmRlbi4gRGFuYWNoIHdlcmRlbiBzaWUgaW4gZWluZW0gRGF0YSBmcmFtZSBhdXNnZWxhZ2VydC4gRGVyIEdydW5kIGRhZsO8ciBpc3QgZWluZmFjaC4gTWl0IGVpbmVtIERhdGEgZnJhbWUgdW5kIG1pdGhpbGZlIHZvbiBkZW0gUGlwZWxpbmUsIEZpbHRlciwgc2VsZWN0LCBtdXRhdGUsdXN3LiBpc3QgZXMgbcO2Z2xpY2ggbnVyIGF1ZiBiZXN0aW1tdGUgTWVya21hbGUgenV6dWdyZWlmZW4gdW5kIGRhcyB2ZXJlaW5mYWNodCBkaWUgVmlzdWFsaXNpZXJ1bmcuDQoNCiMgVW50ZXJzdWNodW5nDQoNCkJlaSBkZXIgQmV0cmFjaHR1bmcgZWluZXMgRGF0ZW5zYXR6ZXMgYnp3IGVpbmVzIEZ1w59iYWxsIERhdGVuc2F0emVzIGthbm4gbWFuIHNpY2ggdW50ZXJzY2hpZWRsaWNoZW4gRnJhZ2VuIHN0ZWxsZW4gdW5kIHp3YXI6DQogMSkgV2FzIHNpbmQgZGllIEFic29sdXRlbiBIw6R1Zmlna2VpdGVuIGRlciB2ZXJmw7xnYmFyZW4gTMOkbmRlcihXaWV2aWVsIG1hbCANCmtvbW1lbiBkaWUgTMOkbmRlciB2b3IpPw0KMikgV2llIHNpZWh0IGRpZSBCZXN1Y2hlcnphaGwgaW0gU3RhZGllbiBhdXM/IEQuaCBpbiB3ZWxjaGVyIExpZ2Egd2VyZGVuIGRpZSBTcGllbGUgbWVociBvZGVyIHdlbmlnZXIgYmVzdWNodD8NCjMpV2FzIGlzdCBEYXMgUHVua3R2ZXJow6RsdG5pcyB6d2lzY2hlbiBkaWUgTMOkbmRlcj8gRC5oIHdpZXZpZWxlIFB1bmt0ZSB3dXJkZW4gaW4gSmVkZW0gTGFuZCBkdXJjaCBkaWUgTWFubnNjaGFmdGVuIGVycmVpY2h0Pw0KNCkgV2VsY2hlIE1hbm5zY2hhZnRlbiB2ZXJsaWVyZW4gYnp3IGdld2lubmVuIHdlbmlnZXIgb2RlciBtZWhyIGFscyBkZW4gU2Nobml0dD8NCjUpV2VsY2hlIE1hbm5zY2hhZnRlbiBTY29yZW4gdmllbCBvZGVyIHdlbmlnZXIgYWxzIGRlbiBTY2huaXR0IHVuZCBpbiB3ZWxjaGVuIEzDpG5kZXIgZ2lidCBlcyBkaWUgYmVzdGVuIFNjb3Jlci4gdXN3Li4NCj09PiB1bmQgVmllbGVzIG1laHIuLg0KRGllc2UgRnJhZ2VuIHdlcmRlbiB3aXIgZWluZmFjaCBtaXRmaGlsZmUgdm9uIGdncGxvdCB1bmQgZ2dwbG90bHkgdmlzdWFsaXNpZXJlbiB1bmQgZGFuYWNoIGludGVycHJldGllcmVuLCB3YXMgd2lyIGVyZnVuZGVuIGhhYmVuLg0KDQoNCg0KIyBIw6R1Zmlna2VpdGVuIGRlciBMw6RuZGVyDQoNCkluIHVuc2VyZW0gRGF0ZW5zYXR6IGdpYnQgZXMgaW5zZ2VzYW10IDk4IE1hbm5zY2hhZnRlbi4gV2lyIHdvbGxlbiBlcnN0bWFsIHNlaGVuLCB3aWUgc2ljaCBkaWUgTWFubnNjaGFmdGVuIGluIGRlbiBMw6RuZGVyIHZlcnRlaWxlbi4gRC5oIHdpZSB2aWVsIE1hbm5zY2hhZnRlbiBqZWRlcyBMYW5kIGJlaW5oYWx0ZXQuIERhZsO8ciBiZW51dHplbiB3aXIgZWluZW4gQmFycGxvdCB1bmQgd2lyIGdyZWlmZW4gYXVmIGRpZSBTcGFsdGUgQ291bnRyeSwgZGllIGRpZSBOYW1lbiBkZXIgTMOkbmRlciBlbnRow6RsdCwgenUuIEFtIEVuZGUgd2lyZCBudW4gZWluZW4gQmFycGxvdCBtaXQgdW50ZXJzY2hpZWRsaWNoZW4gRmFyYmVuIHVuZCBlaW5lIExlZ2VuZGUgaGluenVnZWbDvGd0Lg0KDQoNCg0KDQpgYGB7cn0NCg0KY291bnQ8LXRhYmxlKFgyMDIxXzIwMjJfRm9vdGJhbGxfVGVhbV9TdGF0cyRDb3VudHJ5KQ0KcDI8LWJhcnBsb3QoY291bnQsbWFpbj0iNSAgQmVzdGVuIEV1cm9wYSBNZWlzdGVyc2NoYWZ0ZW4gdW5kIElocmUgSMOkdWZpZ2tlaXRlbiIseGxhYj0iTmFtZSBkZXIgTMOkbmRlciIseWxhYj0iQWJzb2x1dGUgSMOkdWZpZ2tlaXRlbiIsbGVnZW5kPXJvd25hbWVzKGNvdW50KSxjb2w9YygiZ3JlZW4iLCJyZWQiLCJibHVlIiwib3JhbmdlIiwieWVsbG93IikpDQoNCg0KYGBgDQoNCkF1cyBkZXIgVmlzdWFsaXNpZXJ1bmcgaXN0IGVzIHp1IGJlbWVya2VuLCBkYXNzIGRpZSBIw6R1Zmlna2VpdGVuIGRlciBMw6RuZGVyIHBybyBNYW5uc2NoYWZ0IGZhc3QgZ2xlaWNoIGF1c3NpZWh0LiBKZWRlcyBMYW5kIGVudGjDpGx0IGluIHVuc2VyZW0gRGF0ZW5zYXR6IDIwIE1hbm5zY2hhZnRlbiwgbnVyIGRpZSBEZXV0c2NoZSBMaWdhIGJlc3RlaHQgYXVzIDE4IE1hbm5zY2hhZnRlbi4NCg0KIyBNZW5zY2hlbm1hc3NlbiBpbiBTdGFkaWVuDQoNCkhpZXJiZWkgd29sbGVuIHdpciBoZXJhdXNmaW5kZW4sIHdpZSB2aWVsZSBNYW5uc2NoYWZ0ZW4gcHJvIExhbmQgd2VuaWcgYmVzdWNodCB3ZXJkZW4uIERhZsO8ciBuZWhtZW4gd2lyIGRpZSBTcGFsdGUgKkF0dGVuZGFuY2UqLiBEaWVzZSBTcGFsdGUgZW50aMOkbHQgZGllIGR1cmNoc2Nobml0dGxpY2hlIEJlc3VjaGVyemFobCBkZXIgTWFubnNjaGFmdGVuIG5hY2ggMzcgU3BpZWxUYWdlLg0KRGFubiBtYWNoZW4gd2lyIGVpbmUgbXV0YXRlIG1pdCBkZXIgU3BhbHRlICphdmVyYWdlKi4gRGllcyBlbnRzcHJpY2h0IGRlbiBEdXJzY2huaXR0IHZvbiBkZW4gOTggTWFubnNjaGFmdGVuLiBadW0gc2NobHVzcyBtYWNoZW4gd2lyIGVpbmUgRmlsdGVydW5nIHZvbiBMw6RuZGVybiwgZGllIHVudGVyaGFsYiBkZXIgU3BhbHRlICphdmVyYWdlKiBsaWVnZW4gdW5kIHdpciBtYWNoZW4gZWluZSBTZWxla3Rpb24gdm9uIGRlbiBOYW1lIGRlcyBMYW5kZXMoQ291bnRyeSksTmFtZSBkZXIgTWFubnNjaGFmdChTcXVhZCkgdW5kICpBdHRlbmRhbmNlKi4NCkRpZXNlciBIaXN0b2dyYW1tIHdpcmQgUm90IGdlZmFyYnQsdW0gYW56dWRldXRlbiwgZGFzcyBkaWUgTWFubnNjaGFmdGVuICBldHdhcyBzY2hsZWNodGVzIChrbGVpbmUgQmVzdWNoZXJ6YWhsKSBhdWZ3ZWlzZW4NCg0KDQoNCg0KDQpgYGB7cn0NCg0KaGFsbG8yPC0gRXJnICU+JQ0KICBtdXRhdGUoDQogICAgYXZlcmFnZT1zdW0oQXR0ZW5kYW5jZSkvOTgsDQogICAgDQogICkgJT4lDQogIGZpbHRlcihBdHRlbmRhbmNlPGF2ZXJhZ2UpICU+JQ0KICAgICBzZWxlY3QoU3F1YWQsIENvdW50cnksQXR0ZW5kYW5jZSkNCg0KcDwtZ2dwbG90KGhhbGxvMiAsIG1hcHBpbmc9YWVzKHg9Q291bnRyeSkpICsNCiAgZ2VvbV9oaXN0b2dyYW0oZmlsbD0icmVkIiwgY29sb3I9InJlZCIsc3RhdD0iY291bnQiICwgYnJlYWtzPXNlcSgwLCAyMCw0KSkgKw0KICANCiAgbGFicygNCiAgICB0aXRsZT0iNSBCZXN0ZW4gTWVpc3RlcnNjaGFmdGVuIiwgDQogICAgc3VidGl0bGU9IkFuemFobCB2b24gTWFubnNjaGFmdGVuIHBybyBMYW5kIG1pdCB3ZW5pZ2VuIEF0dGVuZGFuY2UiLA0KICAgIHg9Ik5hbWUgdm9uIEzDpG5kZXIiLCANCiAgICB5PSJBYnNvbHV0ZSBIw6R1Zmlna2VpdGVuIg0KICApICsNCiAgY29vcmRfZmxpcCgpDQogIGdncGxvdGx5KHApDQpgYGANCkF1cyBkaWVzZXIgVmlzdWFsaXNpZXJ1bmcgZm9sZ3QsIGRhc3MgYWxsZSBMw6RuZGVyIGF1aGVyaGFsYiBHcm/Dn2JyaXRhbmllbiANCmVpbmUgU2NobGVjaHRlIEJlc3VjaGVyemFobCBiZWkgZGVuIFNwaWVsZW4gYXVmd2Vpc2VuLiBEaWUgc2NoZWNodGVzdGUgRGF2b24gaXN0IEl0YWxpZW4gTWl0IDgwJSBkZXIgTWFubnNjaGFmdGVuIG1pdCBlaW5lciBCZXN1Y2hlcnphaGwgdW50ZXIgZGVtIFNjaG5pdHQuIE51ciBkaWUgRW5nbGlzY2hlIExpZ2Egd2lyZCDDvGJlciA4NSAlIGRlciBTcGllbGUgw7xiZXIgZGVuIFNjaG5pdHQgYmVzdWNodC4NCg0KIyBQdW5rdHZlcmjDpGx0bmlzIGRlciBMw6RuZGVyIHVuZCBQaWUgQ2hhcnQgVmVydGVpbHVuZw0KDQpIaWVyIHdvbGxlbiB3aXIgc2VoZW4gd2lldmllbGUgUHVua3RlIHd1cmRlbiBpbiBqZWRlciBMaWdhbWVpc3RlcnNjaGFmdCBuYWNoDQozNyBTcGllbHRhZ2UgZ2VzYW1tZWx0LiBEYWbDvHIgbWFjaGVuIHdpciBlaW5lIEdydXBwaWVydW5nIG5hY2ggZGVyIFNwYWx0ZSAqQ291bnRyeSouIERhbm4gZGllIFN1bW1lIHZvbiAqUHRzKihQdHMgaXN0IGRhYmVpIGRpZSBlcnJlaWNoZW5kZXRlIFB1bmt0ZSBQcm8gTWFubnNjaGFmdCBuYWNoIDM3IFNwaWVsdGFnZSkuIERpZXNlIFN1bW1lIHdpcmQgZGFubiBQcm8gTGFuZCBqZXdlaWxzIGluIGVpbmVyIG5ldWVuICpNdXRhdGUqIFNwYWx0ZShzdW1tZSkgaGluenVnZWbDvGd0LiBadW0gU2NobHVzcyBtYWNoZW4gd2lyIGVpbmUNClNlbGVrdGlvbiBkZXIgU3BhbHRlbiBDb3VudHJ5KE5hbWUgZGVyIEzDpG5kZXIpLCBTcXVhZChNYW5uc2NoYWZ0IE5hbWUpLHN1bW1lKGRpZSBuZXVlIFNwYWx0ZSkuDQoNCg0KDQoNCg0KYGBge3J9DQoNCmhhbGxvMyA8LSAgRXJnICU+JQ0KICBncm91cF9ieShDb3VudHJ5KSAlPiUNCiAgbXV0YXRlKA0KICAgIHN1bW1lPXN1bShQdHMpLA0KICAgIA0KICApICU+JQ0KICBzZWxlY3QoU3F1YWQsIENvdW50cnksc3VtbWUpDQoNCnAyPC1nZ3Bsb3QoaGFsbG8zLGFlcyhDb3VudHJ5LCBzdW1tZSkpICsgDQogIGdlb21fcG9pbnQoc2l6ZSA9IDMpICsgDQogIGdlb21fbGluZSgpKw0KICBsYWJzKA0KICAgIHRpdGxlPSI1IEJlc3RlbiBMw6RuZGVyIHVuZCBkaWUgU3VtbWUgaWhyZXIgZ2VzYW10ZW4gUHVua3RlbiIsIA0KICAgIHg9Ik5hbWUgdm9uIEzDpG5kZXIiLCANCiAgICB5PSJHZXNhbXRlIFN1bW1lIGRlciBQdW5rdGVuIg0KICApIA0KZ2dwbG90bHkocDIpDQoNCmBgYA0KSW0gendlaXRlbiBQaWUgQ2hhcnQgVmVydGVpbHVuZyBuZWhtZW4gd2lyIGVpbmZhY2ggZGllIHZvcmhlcmlnZW4gYmVyZWNobmV0ZW4gU3VtbWUgUHJvIEzDpG5kZXIgdW5kIFdpciByZXByw6RzZW50aWVyZW4gamVkZXMgTGFuZCBtaXQgc2VpbmVyIFByb3plbnR1YWxlbiBMZWlzdHVuZyBuYWNoIGRlciBTYWlzb24uIEFscyBGYXJiZSBiZW51dHplbiB3aXIgZGllIHVudGVyc2NoaWVkbGljaGVuIEZhcmJlbiBkZXMgUmVnZW5ib2dlbnMsIHVtIGRpZSBMw6RuZGVyIG1pdGVpbmFuZGVyIHp1IHVudGVyc2NoZWlkZW4uDQoNCmBgYHtyfQ0Kc2xpY2VzPC0gYygxMDA5LDEwMDksMTAwMSw4NDUsMTAxMCkNCmxibHM8LWMoIkVuZ2xhbmQiLCJJdGFsaWVuIiwiU3BhbmllbiIsIkRldXRzY2hsYW5kIiwiRnJhbmtyZWljaCIpDQpwY3Q8LXJvdW5kKHNsaWNlcy9zdW0oc2xpY2VzKSoxMDApDQpsYmxzPC1wYXN0ZShsYmxzLCAiICIscGN0LCAiJSIsIHNlcT0iIiApDQpwaWUoc2xpY2VzICxsYWJlbHM9bGJscywgbWFpbj0iUGllIENoYXJ0IFZlcnRlaWx1bmcgZGVyIEzDpG5kZXIgbmFjaCBkZXIgU2Fpc29uIiwgY29sPXJhaW5ib3coNSkpDQoNCmBgYA0KQmVtZXJrZW5zd2VydCBpc3QgZGFzIDQgTMOkbmRlcihGcmFua3JlaWNoLCBHcm/Dn2JyaXRhbm5pZW4sU3BhbmllbiB1bmQgSXRhbGllbikgbmFjaCAzNyBTcGllbHRhZ2UgIGRpZSBnbGVpY2hlIGF1ZmdlcnVuZGV0ZSBMZWlzdHVuZyBlcmJyYWNodCBoYWJlbiBuw6RtbGljaCAyMSUuIE51ciBEZXV0c2NobGFuZCBoYXQgbnVyIDE3JSBlcmJyYWNodC4gRWluIG3DtmdsaWNoZXIgR3J1bmQgZGFmw7xyIGJlc3RlaHQgZGFyaW4sIGRhc3MgZXMgaW4gZGVyICBEZXV0c2NoZW4gTGlnYSBudXIgMTggTWFubnNjaGFmdGVuIGdpYnQsIHdlbm4gZGllIGFuZGVyZW4gw7xiZXIgMjAgTWFubnNjaGFmdGVuIHZlcmbDvGdlbi4gRC5oIGVzIHdpcmQga2F1bSB2b3Jrb21tZW4sIGRhc3MgZGllIGVycmVpY2h0ZSBQdW5rdGUgaW4gRGV1dHNjaGxhbmQgYW0gRW5kZSBkZXIgU2Fpc29uIGdsZWljaCB3aWUgaW4gYW5kZXJlbiBMw6RuZGVyIGF1c3NpZWh0LCBkYSBkaWUgTWFubnNjaGFmdGVuYW56YWhsIGtsZWluZXIgaXN0LiAgDQoNCg0KIyBNYW5uc2NoYWZ0ZW4gbWl0IGd1dGVtIFRvcmRpZmZlcmVueg0KDQpJbiBkaWVzZXIgVmlzdWFsaXNpZXJ1bmcgd29sbGVuIHdpciBiZXN0aW1tZW4sIHdlbGNoZSBNYW5uc2NoYWZ0ZW4gZWluZSBndXRlIFRvcmRpZmZlcmVueiBiZXNpdHp0LiBEYWbDvHIgYmVuw7Z0aWdlbiB3aXIgZGllIFNwYWx0ZSAqR0QqKEdvYWwgRGlmZmVyZW5jZSA9VG9yZSBlcnppZWx0IG1pbnVzIFRvcmUgS2Fzc2llcnQpLiBEaWVzZSBTcGFsdGUgZW50aMOkbHQgZGFubiBkaWUgVG9yZGlmZmVyZW56IHZvbiBqZWRlciBNYW5uc2NoYWZ0IG5hY2ggMzcgU3BpZWx0YWdlLiBXaXIgbWFjaGVuIGRhbm4gZWluZSBNdXRhdGUgbWl0IGRlciBTcGFsdGUgKmF2ZXJhZ2UqLiBEaWVzIGVudHNwcmljaHQgZGVuIFNjaG5pdHQgZGVyIFRvcmRpZmZlcmVuemVuIGFsbGVyIE1hbm5zY2hhdGVuLiBEYW5hY2ggbWFjaGVuIHdpciBlaW5lIEZpbHRlcnVuZyBkZXIgTWFubnNjaGFmdGVuIGRpZSBvYmVyaGFsYiBkZXIgQXZlcmFnZSBsaWVnZW4gdW5kIHp1bSBTY2hsdXNzIGVpbmUgU2VsZWt0aW9uIGRlciBTcGFsdGVuKFNxdWFkLCBHRCB1bmQgYXZlcmFnZSkgDQpgYGB7cn0NCmhhbGxvNzwtRXJnICU+JQ0KICBtdXRhdGUoDQogICAgYXZlcmFnZT1zdW0oR0QpLzk4DQogICkgJT4lDQogIGZpbHRlcihHRD4gYXZlcmFnZSkgJT4lDQogc2VsZWN0KFNxdWFkLEdELGF2ZXJhZ2UpDQoNCnA2PC1nZ3Bsb3QoaGFsbG83KSArDQogIGdlb21fcG9pbnQobWFwcGluZz1hZXMoeD1HRCwgeT1TcXVhZCksIA0KICAgICAgICAgICAgIGNvbG9yPSJicm93biIsZmlsbD0iYnJvd24iKSArDQogIGxhYnMoDQogICAgdGl0bGU9IiBndXRlIE1hbm5zY2hhZnRlbiBtaXQgVG9yZGlmZmVyZW56IG9iZXIgZGVuIFNjaG5pdHQgIiwgDQogICAgeT0iTmFtZSB2b24gTWFubnNjaGFmdGVuIiwgDQogICAgeD0iVG9yZGlmZmVyZW56IGRlciBNYW5uc2NoYWZ0ZW4iDQogICkgDQpnZ3Bsb3RseShwNikNCg0KDQoNCmBgYA0KQXVzIGRpZXNlciBWaXN1YWxpc2llcnVuZyBsw6Rzc3Qgc2ljaCBoZXJhdXNmaW5kZW4sZGFzcyB1bmdlZsOkaHIgNDYlIGRlciB2ZXJmw7xnYmFyZW4gTWFubnNjaGFmdGVuIGVpbmUgVG9yZGlmZmVyZW56IMO8YmVyIGRlbiBEdXJjaHNjaG5pdHQgYmVzaXR6ZW4uIERhYmVpIGlzdCBpbW1lciBkaWUgZW5nbGlzY2hlIE1laXN0ZXJzY2hhZnQgYW4gZGVyIFNwaXR6ZSBtaXQgbWVociBhbHMgZWluIGRyaXR0ZWwgIGRlciBNYW5uc2NoYWZ0ZW4gdW5kIGFuIGxldHp0ZW4gU3RlbGxlIHN0ZWh0IGRpZSBJdGFsaWVuaXNjaGUgTWVpc3RlcnNjaGFmdCBtaXQgbnVyIDcgTWFubnNjaGFmdGVuLg0KDQojIE1hbm5zY2hhZnRlbiBkaWUgbWVociBhbHMgZGVuIFNjaG5pdHQgZ2V3b25uZW4gaGFiZW4NCg0KSGllcmJlaSB3b2xsZW4gd2lyIGRpZSBNYW5uc2NoYWZ0ZW4sIGRpZSDDvGJlciBkZW4gU2Nobml0dCBnZXdpbm5lbi5EYWJlaSBncmVpZmVuIHdpciBhdWYgZGllIFNwYWx0ZSAqVyogenUuIERpZXNlIFNwYWx0ZSBlbnRow6RsdCBhbGxlIGdld29ubmVuZW4gU3BpZWxlIGRlciBNYW5uc2NoYWZ0ZW4gbmFjaCAzNyBTcGllbGUuIFdpciBtYWNoZW4gd2llIMO8YmxpY2ggZWluZSBuZXVlIFNwYWx0ZSwgZGllIGRpZSBBdmVyYWdlIGRlciBnZXdvbm5lbmVuIFNwaWVsZSBiZXJlY2huZXQgdW5kIGFtIEVuZGUgZWluZSBGaWx0ZXIgZGVyIE1lcmttYWxlIGRpZSBvYmVyaGFsYiBsaWVnZW4gdW5kIGVpbmUgU2VsZWt0aW9uIGRlciBTcGFsdGVuKFNxdWFkLCBXIHVuZCBkaWUgbmV1ZSBTcGFsdGUgQXZlcmFnZSkuDQoNCg0KYGBge3J9DQpoYWxsbzU8LUVyZyAlPiUNCiAgbXV0YXRlKA0KICAgIGF2ZXJhZ2U9c3VtKFcpLzk4DQogICkgJT4lDQogIGZpbHRlcihXPiBhdmVyYWdlKSAlPiUNCiBzZWxlY3QoU3F1YWQsVyxhdmVyYWdlKQ0KcDM8LWdncGxvdChoYWxsbzUpICsNCiAgZ2VvbV9wb2ludChtYXBwaW5nPWFlcyh4PVcsIHk9U3F1YWQpLCANCiAgICAgICAgICAgICBjb2xvcj0iYmx1ZSIsZmlsbD0iYmx1ZSIpICsNCiAgbGFicygNCiAgICB0aXRsZT0iIEJlc3RlIE1hbm5zY2hhZnRlbiBkaWUgdWViZXIgZGVyIEF2ZXJhZ2UgZ2V3aW5uZW4iLCANCiAgICB5PSJOYW1lIHZvbiBNYW5uc2NoYWZ0ZW4iLCANCiAgICB4PSJBbnphaGwgdm9uIGdld29ubmVuZW4gU3BpZWxlbiINCiAgKQ0KZ2dwbG90bHkocDMpDQoNCmBgYA0KQmVpIGRlciBHZXdpbm5xdW90ZSB6ZWlndCBpbW1lciBub2NoIGRpZSBFbmdsaXNjaGUgTWVpc3RlcnNjaGFmdCwgd2FydW0gc2llIGFscyAqYmVzdGUgRnVzc2JhbGwgTGlnYSogZ2lsdC4gIE1hbmNoZXN0ZXIgY2l0eSBhdXMgRW5nbGFuZCBzdGVodCBpbW1lciBub2NoIGFuIGRlciBTcGl0emUgbWl0IG1laHIgYWxzIGRlbiBEb3BwZWwgZGVzIER1cmNoc2Nobml0dHMuIEhpZXJiZWkgaXN0IGRpZSBmcmFuesO2c2lzY2hlIExpZ2EgYW4gZGVyIGxldHp0ZW4gU3RlbGxlIG1pdCB3ZW5pZ2VuIE1hbm5zY2hhZnRlbiBEYWJlaS4NCg0KIyBTcGllbGVyIG1pdCBkZXIgQmVzdGVuIEdQTUEoVG9yIHBybyBTcGllbCBEdXJjaHNjaG5pdHQpDQoNCkdQTUE9QW56YWhsIHZvbiBlcnppZWx0ZW4gVG9yZW4vIEFuemFobCB2b24gU3BpZWxlbg0KLg0KWnVtIGVyc3RlbiB3aXJkIGVpbmVuIG5ldWVuIERhdGVuc2F0eiAqaGFsbG9ndCogZXJzdGVsbHQsIHdvYmVpIGRpZSBTcGFsdGUgKlRvcCBUZWFtIFNjb3JlciogaW4gWndlaSBTcGFsdGVuKCpCZXN0U2NvcmVyKiB1bmQgKkdvYWxTY29yZWQqKSBnZXRlaWx0IHdpcmQuIEVpbmUgU3BhbHRlIG1pdCBkZW0gTmFtZSBkZXMgU2NoaWXDn2VycyB1bmQgZWluZSBhbmRlcmUgTWl0IHNlaW5lbiBlcnppZWx0ZW4gVG9yZW4uDQpEYW5hY2ggZXJ6ZXVnZW4gd2lyIGRpZSBTcGFsdGUgKkdQTUEqIHVuZCBkaWUgU3BhbHRlICpBdmVyYWdlKiAuIEdQTUEgZW50c3ByaWNodCBkZW4gVG9yc2Nobml0dCB2b24gamVkZW0gU3BpZWxlciBuYWNoIGRlciBBbnphaGwgZGVyIGdlc3BpZWx0ZW4gU3BpZWxlLiBBdmVyYWdlIGlzdCBlaW5mYWNoIGRlciBTY2huaXQgZGVyICpHUE1BKiBhbGxlciBNYW5uc2NoYWZ0ZW4uDQoNCmBgYHtyfQ0KaGFsbG9ndDwtRXJnICU+JSBzZXBhcmF0ZShjb2wgPSAiVG9wIFRlYW0gU2NvcmVyIiwgaW50byA9IGMoIkJlc3RTY29yZXIiLCJHb2FsU2NvcmVkIiksIHNlcD0iIC0gIikNCg0KaGFsbG8xMTwtIGhhbGxvZ3QgJT4lDQogIG11dGF0ZSgNCiAgICBHUE1BPWFzLm51bWVyaWMoR29hbFNjb3JlZCkvTVAsDQogICAgQXZlcmFnZT1zdW0oR1BNQSkvOTgNCiAgICANCiAgKSAlPiUgDQogIGZpbHRlcihHUE1BPiBBdmVyYWdlKSAlPiUNCiAgc2VsZWN0KEJlc3RTY29yZXIsIEdvYWxTY29yZWQgLEdQTUEsQ291bnRyeSkNCnA5PC1nZ3Bsb3QoaGFsbG8xMSkgKw0KICBnZW9tX3BvaW50KG1hcHBpbmc9YWVzKHg9R1BNQSAsIHk9QmVzdFNjb3JlciApLCANCiAgICAgICAgICAgICBjb2xvcj0ibWFyb29uIixmaWxsPSJtYXJvb24iKSArDQogIGxhYnMoDQogICAgdGl0bGU9IiAgU2NoaWVzc2VyIGRpZSDDvGJlciBkZW4gR1BNQSBzY29yZW4iLCANCiAgICB5PSJOYW1lIGRlciBTcGllbGVyIiwgDQogICAgeD0iVG9yIHBybyBTcGllbCBEdXJjaHNjaG5pdHQgZGVyIFNwaWVsZXIiDQogICkNCmdncGxvdGx5KHA5KQ0KDQpgYGANCg0KDQojIFNjaGllc3N2ZXJow6RsdG5pcyB6d2lzY2hlbiBkaWUgTGlnYXMgbWl0IEJlc3RTY2hpZcOfZXIgw7xiZXIgZGVuIFNjaG5pdHQNCg0KWnVtIGVyc3RlbiB3aXJkIGVpbmVuIG5ldWVuIERhdGFmcmFtZSAqaGFsbG9ndCogZXJzdGVsbHQsIHdvYmVpIGRpZSBTcGFsdGUgKlRvcCBUZWFtIFNjb3JlciogaW4gWndlaSBTcGFsdGVuKCpCZXN0U2NvcmVyKiB1bmQgKkdvYWxTY29yZWQqKSBnZXRlaWx0IHdpcmQuIEVpbmUgU3BhbHRlIG1pdCBkZW0gTmFtZSBkZXMgU2NoaWXDn2VycyB1bmQgZWluZSBhbmRlcmUgTWl0IHNlaW5lbiBlcnppZWx0ZW4gVG9yZW4uDQpEYW5hY2ggbWFjaGVuIHdpciBlaW5lIEdydXBwaWVydW5nIMO8YmVyIGRpZSBTcGFsdGUgKkNvdW50cnkqIA0KdW5kIGVpbmUgIG5ldWUgU3BhbHRlICpBdmVyYWdlKiB3aXJkIGhpbnp1Z2Vmw7xndC4gRGllcyBlbnRow6RsdCBkZW4gU2Nobml0dCBkZXIgZXJ6aWVsdGVuIFRvcmVuIHVuZCBhbSBFbmRlIG1hY2hlbiB3aXIgZWluZSBTZWxla3Rpb24gZGVyIGVyemllbHRlbiBUb3JlIG9iZXJoYWxiIGRlciBBdmVyYWdlIA0KDQpgYGB7cn0NCmhhbGxvZ3Q8LUVyZyAlPiUgc2VwYXJhdGUoY29sID0gIlRvcCBUZWFtIFNjb3JlciIsIGludG8gPSBjKCJCZXN0U2NvcmVyIiwiR29hbFNjb3JlZCIpLCBzZXA9IiAtICIpDQoNCmhhbGxvMTA8LWhhbGxvZ3QgJT4lDQogIGdyb3VwX2J5KENvdW50cnkpJT4lDQogIG11dGF0ZSgNCiAgICBBdmVyYWdlPXN1bShhcy5udW1lcmljKEdvYWxTY29yZWQpKS85OA0KICAgIA0KICApICU+JSANCiAgZmlsdGVyKEdvYWxTY29yZWQgPiBBdmVyYWdlKSAlPiUNCiAgc2VsZWN0KEJlc3RTY29yZXIsIEdvYWxTY29yZWQgLEF2ZXJhZ2UsQ291bnRyeSkNCg0KcDg8LWdncGxvdChoYWxsbzEwICwgbWFwcGluZz1hZXMoeD1Db3VudHJ5KSkgKw0KICAgICBnZW9tX2JhcihmaWxsPSJvcmFuZ2UiLCBjb2xvcj0iYmxhY2siKSArDQogICAgIGxhYnMoDQogICAgICAgICB0aXRsZT0iIExpZ2FzIEdvYWxhdXNnbGVpY2giLCANCiAgICAgICAgIHN1YnRpdGxlPSIgTGlnYXMgbWl0IG1laHIgdW5kIFdlbmlnZXIgQmVzdFNjaGllw59lciIsDQogICAgICAgICB4PSJOYW1lIHZvbiBMw6RuZGVyIiwgDQogICAgICAgICB5PSJBbnphaGwgZGVyIEJlc3RTY2hpZcOfZXIgcHJvIExhbmQiDQogICAgICkgDQpnZ3Bsb3RseShwOCkNCg0KYGBgDQoNCkRpZSBEZXV0c2NoZSBMaWdhIGhhdCB3ZW5pZ2UgTWFubnNjaGFmdGVuIGFscyBkaWUgYW5kZXJlIEzDpG5kZXIgYWJlciBiZXNpdHp0IGVpbiBEcml0dGVsIGRlciBiZXNzZXJlbiBUb3JlU2NoaWXDn2VyIGRlciBsZXJ0enRlbiBTYWlzb24uIFp1IGJlYWNodGVuIGlzdCwgZGFzcyBJdGFsaWVuIG1pdCBudXIgNiBCZXRlaWxpZ3RlbiBzdGVodCBpbW1lciBhbiBkZXIgbGV0enRlbiBTdGVsbGUuIERpZSBJdGFsaWVuaXNjaGUgTGlnYSB3aXJkIG5pY2h0IG51ciB1bnRlciBkZW4gU2Nobml0dCBiZXNpY2h0aWd0LCBzb25kZXJuIGRpZSBNYW5uc2NoYWZ0ZW4gdW5kIFNwaWVsZXIgc2NoaWXDn2VuIG5pY2h0IHNvIHZpZWxlLiBEaWVzZSBHcsO8bmRlIHdlaXNlbiBlaW5mYWNoIG5hY2gsIHdhcnVtIGRpZSBJdGFsaWVuaXNjaGUgTGlnYSBhbHMgKnNjaHdlcmUqIExpZ2EgZ2VrZW5uemVpY2huZXQgd2lyZC4NCg0KIyDDvGJlcnJhc2NoZW5kZSBFcmdlYm5pc3NlDQoNCmVpbiBncsO2w59lcyDDvGJlcnJhc2NoZW5kZXMgRXJnZWJuaXMgYmVzdGVodCBkYXJpbiwgZGFzcyBpbnNnZXNhbXQgNCBNZWlzdGVyc2NoYWZ0ZW4oR3Jvw59icml0YW5uaWVuLCBGcmFua3JlaWNoLCBJdGFsaWVuIHVuZCBTcGFuaWVuKSBkaWUgZ2xlaWNoZSBhdWZnZXJ1bmRldGUgTGVpc3R1bmcoamV3ZWlscyAyMSUgZGVyIHB1bmt0ZW4pIGFtIEVuZGUgZGVyIFNhaXNvbiBnZXNhbW1lbHQgaGFiZW4uIFNpZSB2ZXJmw7xnZW4gw7xiZXIgdW50ZXJzY2hpZWRsaWNoZSBUb3JkaWZmZXJueiwgRXJ3YXJ0ZXRlIFRvcmVuICwgQmVzdHNjaGllw59lciB1bmQgYmVpIG1hbmNoZW4gTWVpc3RlcnNjaGFmdGVuIGdpYnQgZXMgc29nYXIgbWVociBhbHMgNTAgJSBkZXIgTWVpc3RlcnNjaGFmdGVuLCBkaWUgd2VuaWcgVG9yZSBlcnppZWxlbi4gV2lyIGvDtm5uZW4gZGFydW50ZXIgdmVyc3RlaGVuLCBkYXNzIGRpZSBUb3JxdW90ZSBlaW5lciBNYW5uc2NoYWZ0IGtlaW5lbiBTdMOkcmtlcmVuIEVpbmZsdXNzIGF1ZiBkZW4gR2V3aW5uIG9kZXIgVmVybHVzdCBlaW5lcyBTcGllbHMgaGF0Lg0KDQpFaW5lIHdlaXRlcmUgw5xiZXJyYXNjaHVuZyBsaWVndCBkYXJhbiwgZGFzcyBkaWUgRGV1dHNjaGUgTWVpc3RlcnNjaGFmdCB3ZW5pZ2UgU3BpZWxlciBiencgU3TDvHJtZXIgaGF0LCB3ZWlsIHNpZSBudXIgMTggTWFubnNjaGFmdGVuIGhhdCwgd2VubiBkaWUgYW5kZXJlbiBMaWdhcyDDvGJlciAyMCBWZXJmw7xnZW4uIFNpZSBhYmVyIGRpZSBMaWdhIG1pdCBkZW4gYmVzdGVuIFN0w7xybWVyIGRpZSBtZWhyIGFscyBkZW4gU2Nobml0dCBzY2hpZcOfZW4uDQoNCg0KIyBLcmlzdGlzY2hlciBBdXNibGljaw0KDQpFcyBpc3QgaW1tZXIgc2Nod2VyIHNlaW5lIGVpZ2VuZSBBcmJlaXQgenUgYmV1cnRlaWxlbiwgYWJlciBudXIgZGllIGVpZ2VuZSBCZWl0ZWlsaWd0ZW4gd2lzc2VuLCB3ZWxjaGVyIEF1ZndhbmQgdW5kIHdlbGNoZSBTY2h3aWVyaWdrZWl0ZW4gc2llIGJlaSBkZXIgRXJsZWRpZ3VuZyBkZXIgQXJiZWl0IGVybGVidCBoYWJlbi4gSW4gZGllc2VyIEFyYmVpdCB3YXIgZGllIElkZWUgbWl0IGVpbmVtIEZsZXhkYXNoYm9hcmQoaW4gZGVuIGJlaWRlbiBlcnN0ZW4gdmVyc2lvbmVuKSBkaWUgRGF0ZW4genUgdmlzdWFsaXNpZXJlbiAgdW5nZWVpZ25ldC4gRGVyIEdydW5kIGRhZsO8ciBpc3QgZWluZmFjaC4gRGFtaXQga2FubiBtYW4gbmljaHQgZ2xlaWNoemVpdGlnIHZpc3VhbGlzaWVyZW4gdW5kIFRleHQgaGluenVmw7xnZW4sIGJ6dyBkZW4gQ29kZSBhbnNlaGVuLiBBYmVyIG5hY2ggendlaSBWZXJzaW9uZW4gaXN0IGVpbiAqTm90ZWJvb2sqIGbDvHIgZGllc2UgVmlzdWFsaXNpZXJ1bmcgenVtIEVpbnNhdHogZ2Vrb21tZW4gdW5kIGhhdCB1bnMgZGllIFNhY2hlbiBlcmxlaWNodGVydCB1bmQgZGllIFZpc3VhbGlzaWVydW5nZW4gaXN0IHVuc2VyZXIgTWVpbnVuZyBuYWNoIG5hY2h2b2xsemllaGJhcmVyIGdld29yZGVuLiBCZXNzZXIgaMOkdHRlbiB3aXIgZGlyZWt0IG1pdCBlaW5lbSBOb3RlYm9vayBhbmdlZmFuZ2VuIHVuZCB3aXIgd8OkcmVuIGZyw7xoIGZlcnRpZyBnZXdvcmRlbi4gQWJlciBkaWVzIGhhdCB1bnMgZXJtw7ZnbGljaHQgc293b2hsIG1pdCBGbGV4ZGFzaGJvYXJkIGFscyBhdWNoIE5vdGVib29rIHp1IGFyYmVpdGVuLiBEYXMga2FubiBmw7xyIHVucyBudXIgZWluIFZvcnRlaWwgc2Vpbi4NCg0KVmVyd2VuZGV0ZSBRdWVsbGVuDQpodHRwczovL3d3dy5kZWxmdHN0YWNrLmNvbS9kZS9ob3d0by9yL3NlcGFyYXRlLWluLXIvOiAgV3VyZGUgYmVudXR6dCwgd2VpbCB3aXIgZWluZSBTcGFsdGUgaW4gendlaSBTcGFsdGVuIGF1ZnRlaWxlbiB3b2xsdGVuLg0KDQpDaGFyYWN0ZXIgRW5jb2RpbmcgaW4gdGhlIFJTdHVkaW8gSURFIOKAkyBSU3R1ZGlvIFN1cHBvcnQ6ICBNaXQgVVRGLTggaGFiZW4gd2lyICBQcm9ibGVtZSB6dW0gRWlubGVzZW4gTWFuY2hlIENoYXJha3RlciBnZWtyaWVndCBEYWhlciBoYWJlbiB3aXIgdW5zIGRpZXNlIEVuY29kaW5nIFF1ZWxsZSBTZWl0ZSBhbmdlc2NoYXV0LCB1bSB1bnNlcmUgcGFzc2VuZGUgRW5jb2RpbmcgYXVzenV3w6RobGVuLg0KDQoJR2VsZWlzdGV0ZW4gQXJiZWl0c3plaXQNCiBadXIgRXJsZWRpZ3VuZyBkaWVzZXIgQXJiZWl0IGhhYmVuIHdpciB1bmdlZsOkaHIgNDcgU3R1bmRlbi4oaW5uZXJoYWxiIDQgV29jaGVuKSBmw7xyIGRpZSBlcnN0ZSBWZXJzaW9uIGdlYnJhdWNodC4gRsO8ciBkaWUgendlaXRlIFZlcnNpb24gMTAgU3R1bmRlbiBpbm5lcmhhbGIgZWluZXIgV29jaGUuRsO8ciBkaWUgZHJpdHRlIFZlcnNpb24gaGFiZW4gd2lyIDIzIFN0dW5kZW4gZ2VicmF1Y2h0LCB1bSBlcyAgZmVydGlnenVzdGVsbGVuLiBEYXMgZXJnaWJ0IGVpbmUgZ2VzYW10ZSBBcmJlaXRzYXVmd2FuZCB2b24gODAgU3R1bmRlbi4NCg0KDQoNCiANCg0KDQo=